package com.youhome.service.service.impl;

import com.youhome.common.enums.ZilLowSearchTypeEnum;
import com.youhome.common.enums.ZillowTypeEnum;
import com.youhome.common.exception.CustomException;
import com.youhome.service.model.ZipCode;
import com.youhome.service.response.*;
import com.youhome.service.service.DownloadService;
import com.youhome.service.service.ZilLowByCityService;
import com.youhome.service.service.ZipCodeService;
import com.youhome.service.utils.StateUtils;
import com.youhome.service.utils.ZillowJsonExtractUtils;
import com.youhome.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * Created by chen365 on 2019/04/12.
 */
@Service
public class ZilLowByCityServiceImpl implements ZilLowByCityService {

    @Autowired
    private DownloadService downloadService;

    @Autowired
    private ZipCodeService zipCodeService;

    @Override
    public List<TimeValueItemResult> getTimeSeriesByCity(Integer type, String city, String state, Integer year) throws CustomException {
        String dir = ZillowTypeEnum.getEnumByKey(type).getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city);

        if (type.equals(ZillowTypeEnum.DaysOnZillow_City.getKey()) || type.equals(ZillowTypeEnum.DaysOnZillow_City_Repeat.getKey())) {
            filename = StringUtils.replaceBlankAndComma(city) +
                    "_" + StringUtils.replaceBlankAndComma(state);
        }

        if (type.equals(ZillowTypeEnum.Sale_Counts_Seas_Adj_City.getKey()) || type.equals(ZillowTypeEnum.Sale_Counts_Seas_Adj_City_Repeat.getKey())) {
            filename = StringUtils.replaceBlankAndComma(city) +
                    "_" + StringUtils.replaceBlankAndComma(StringUtils.stateAbbreviationToAll(state));
        }

        if (type.equals(ZillowTypeEnum.SaleToListRatio_City.getKey()) || type.equals(ZillowTypeEnum.SaleToListRatio_City_Repeat.getKey())) {
            filename = StringUtils.replaceBlankAndComma(city) +
                    "_" + StringUtils.replaceBlankAndComma(state);
        }

        String key = "zillow/" + dir + "/" + filename + ".json";

        System.err.println(key);

        String json = downloadService.downloadJsonFromOSS(key);
        //如果 city + state 结果，则通过 zipcode 映射 取得 county ，用 city+state+county 接接地址，取第一个有值 json
        if (StringUtils.isEmpty(json)) {
            json = selectJsonByStateCity(dir, city, state);
        }
        return ZillowJsonExtractUtils.dislodgeEmptyItem(ZillowJsonExtractUtils.getSeriesDataByYear(json, year));
    }

    @Override
    public List<TimeValueItemResult> getTimeSeriesByCity(Integer type, String zip, Integer year) throws CustomException {
        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            //去掉 County  字符串，提高准确率
            String county = zipCode.getCounty().replaceAll(" County", "").trim();

            //先按 city + state 查询
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                List<TimeValueItemResult> timeSeriesByCity = getTimeSeriesByCity(type, city, state, year);
                if (timeSeriesByCity != null && timeSeriesByCity.size() > 0) {
                    return timeSeriesByCity;
                } else {
                    //如果按city + state 查询 结果，则再按 city + state + county 查询
                    if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city) && !StringUtils.isEmpty(county)) {
                        return getTimeSeriesByCity(type, city, state, county, year);
                    }
                }
            }
        }
        return null;
    }

    @Override
    public List<TimeValueItemResult> getTimeSeriesByCity(Integer type, String zip, Integer year, ZilLowSearchTypeEnum zilLowSearchTypeEnum) throws CustomException {
        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            //去掉 County  字符串，提高准确率
            String county = zipCode.getCounty().replaceAll(" County", "").trim();
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                if (zilLowSearchTypeEnum == ZilLowSearchTypeEnum.STATE_CITY) {
                    //city + state 查询
                    return getTimeSeriesByCity(type, city, state, year);
                } else if (zilLowSearchTypeEnum == ZilLowSearchTypeEnum.STATE_CITY_COUNTY) {
                    //按 city + state + county 查询
                    if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city) && !StringUtils.isEmpty(county)) {
                        return getTimeSeriesByCity(type, city, state, county, year);
                    }
                }
            }
        }
        return null;
    }

    @Override
    public List<TimeValueItemResult> getTimeSeriesByCity(Integer type, String city, String state, String county, Integer year) throws CustomException {

        String dir = ZillowTypeEnum.getEnumByKey(type).getValue();

//        String filename = StringUtils.replaceBlankAndComma(state) +
//                "_" + StringUtils.replaceBlankAndComma(city) +
//                "_" + StringUtils.replaceBlankAndComma(county);

        String filename = joinJsonName(type, city, state, county);

        String key = "zillow/" + dir + "/" + filename + ".json";

        System.err.println(key);

        String json = downloadService.downloadJsonFromOSS(key);

        return ZillowJsonExtractUtils.dislodgeEmptyItem(ZillowJsonExtractUtils.getSeriesDataByYear(json, year));

    }

    @Override
    public BuyerSellerResult get_Buyer_Seller_Index_City(String city, String state) throws CustomException {
        String dir = ZillowTypeEnum.BuyerSellerIndex_City.getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city);

        String key = "zillow/" + dir + "/" + filename + ".json";

        System.err.println(key);

        String json = downloadService.downloadJsonFromOSS(key);

        return ZillowJsonExtractUtils.extractBuyerSellerResultByJson(json);
    }

    @Override
    public BuyerSellerResult get_Buyer_Seller_Index_City(String zip) throws CustomException {
        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                return get_Buyer_Seller_Index_City(city, state);
            }
        }
        return null;
    }

    @Override
    public BuyerSellerResult get_Buyer_Seller_Index_City(ZipCode zipCode) throws CustomException {
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                return get_Buyer_Seller_Index_City(city, state);
            }
        }
        return null;
    }

    @Override
    public ZhviResult get_City_Zhvi_Summary_AllHomes(String zip) throws CustomException {
        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            String county = zipCode.getCounty();

            //房屋价格指数是按 city + state +county 命名的，直接按  city + state +county 查询
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city) && !StringUtils.isEmpty(county)) {
                return get_City_Zhvi_Summary_AllHomes(city, state, county);
            }
        }
        return null;
    }

    @Override
    public ZhviResult get_City_Zhvi_Summary_AllHomes(String city, String state) throws CustomException {
        String dir = ZillowTypeEnum.City_Zhvi_Summary_AllHomes.getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city);

        String key = "zillow/" + dir + "/" + filename + ".json";

        String json = downloadService.downloadJsonFromOSS(key);
        //如果 city + state 结果，则通过 zipcode 映射 取得 county ，用 city+state+county 接接地址，取第一个有值 json
        if (StringUtils.isEmpty(json)) {
            json = selectJsonByStateCity(dir, city, state);
        }
        return ZillowJsonExtractUtils.extractZhviResultByJson(json);
    }

    @Override
    public ZhviResult get_City_Zhvi_Summary_AllHomes(String city, String state, String county) throws CustomException {
        String dir = ZillowTypeEnum.City_Zhvi_Summary_AllHomes.getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city) +
                "_" + StringUtils.replaceBlankAndComma(county);

        String key = "zillow/" + dir + "/" + filename + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);

        return ZillowJsonExtractUtils.extractZhviResultByJson(json);
    }

    @Override
    public ZriResult get_City_Zri_AllHomes_Summary(Integer type, String zip) throws CustomException {
        ZipCode zipCode = zipCodeService.selectShortByPrimaryKey(zip);
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            String county = zipCode.getCounty();

            //房屋房租指数是按city + state + county 命名，直接 city + state + county 查询
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city) && !StringUtils.isEmpty(county)) {
                return get_City_Zri_AllHomes_Summary(type, city, state, county);
            }
        }
        return null;
    }

    @Override
    public ZriResult get_City_Zri_AllHomes_Summary(Integer type, String city, String state) throws CustomException {
        String dir = ZillowTypeEnum.getEnumByKey(type).getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city);

        String key = "zillow/" + dir + "/" + filename + ".json";

        System.err.println(key);

        String json = downloadService.downloadJsonFromOSS(key);
        //如果 city + state 结果，则通过 zipcode 映射 取得 county ，用 city+state+county 接接地址，取第一个有值 json
        if (StringUtils.isEmpty(json)) {
            json = selectJsonByStateCity(dir, city, state);
        }
        return ZillowJsonExtractUtils.extractZriResultByJson(json);
    }

    @Override
    public ZriResult get_City_Zri_AllHomes_Summary(Integer type, String city, String state, String county) throws CustomException {

        String dir = ZillowTypeEnum.getEnumByKey(type).getValue();

        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city) +
                "_" + StringUtils.replaceBlankAndComma(county);

        String key = "zillow/" + dir + "/" + filename + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(key);

        return ZillowJsonExtractUtils.extractZriResultByJson(json);
    }

    @Override
    public MarketHealthResult get_Market_Health_Index_City(String city, String state) throws CustomException {
        String dir = ZillowTypeEnum.MarketHealthIndex_City.getValue();
        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city);

        String key = "zillow/" + dir + "/" + filename + ".json";

        System.err.println(key);

        String json = downloadService.downloadJsonFromOSS(key);
        //如果 city + state 结果，则通过 zipcode 映射 取得 county ，用 city+state+county 接接地址，取第一个有值 json
        if (StringUtils.isEmpty(json)) {
            json = selectJsonByStateCity(dir, city, state);
        }
        return ZillowJsonExtractUtils.extractMarketHealthResultByJson(json);
    }

    @Override
    public MarketHealthResult get_Market_Health_Index_City(ZipCode zipCode) throws CustomException {
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();
            //市场健康指数是按 city + state 命名的，直接按  city + state 查询
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                return get_Market_Health_Index_City(city, state);
            }
        }
        return null;
    }

    @Override
    public List<TimeValueItemResult> getTimeSeriesByCity(Integer type, ZipCode zipCode, Integer year, ZilLowSearchTypeEnum zilLowSearchTypeEnum) throws CustomException {
        if (zipCode != null) {
            String city = zipCode.getPrimaryCity();
            String state = zipCode.getState();

            String county = zipCode.getCounty();
            if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city)) {
                if (zilLowSearchTypeEnum == ZilLowSearchTypeEnum.STATE_CITY) {
                    //city + state 查询
                    return getTimeSeriesByCity(type, city, state, year);
                } else if (zilLowSearchTypeEnum == ZilLowSearchTypeEnum.STATE_CITY_COUNTY) {
                    //按 city + state + county 查询
                    if (!StringUtils.isEmpty(state) && !StringUtils.isEmpty(city) && !StringUtils.isEmpty(county)) {
                        List<TimeValueItemResult> result = getTimeSeriesByCity(type, city, state, county, year);
                        if (result == null) { //如果没有查询到，尝试去除郡县里的“County” 字符
                            county = zipCode.getCounty().replaceAll(" County", "").trim();
                            result = getTimeSeriesByCity(type, city, state, county, year);
                        }
                        return result;
                    }
                }
            }
        }
        return null;
    }

    @Override
    public BreakEvenPRResult get_Break_Even_PR(Integer key, ZipCode zipCode, Integer year, ZilLowSearchTypeEnum stateCityCounty) {
        String dir = ZillowTypeEnum.getEnumByKey(key).getValue();

        String filename = StringUtils.replaceBlankAndComma("city") + "_" //RegionType
                + StringUtils.replaceBlankAndComma(zipCode.getPrimaryCity()) + "_"//City
                + StringUtils.replaceBlankAndComma(zipCode.getCounty()) + "_"//CountyName
                + StringUtils.replaceBlankAndComma(zipCode.getState()); //StateName

        String path = "zillow/" + dir + "/" + filename + ".json";
        System.err.println(key);
        String json = downloadService.downloadJsonFromOSS(path);
        if(StringUtils.isEmpty(json)){


            filename = StringUtils.replaceBlankAndComma("city") + "_" //RegionType
                    + StringUtils.replaceBlankAndComma(zipCode.getPrimaryCity()) + "_"//City
                    + StringUtils.replaceBlankAndComma(zipCode.getCounty().replaceAll("County","").trim()) + "_"//CountyName
                    + StringUtils.replaceBlankAndComma(zipCode.getState()); //StateName


            path = "zillow/" + dir + "/" + filename + ".json";
            json = downloadService.downloadJsonFromOSS(path);
        }

        return ZillowJsonExtractUtils.extractBreakEvenPRResultByJson(json);

    }


    public String selectJsonByStateCity(String dir, String city, String state) {
        //如果 city + state 结果，则通过 zipcode 映射 取得 county ，用 city+state+county 接接地址，取第一个有值 json
        String json = null;

        ZipCode record = new ZipCode();
        record.setPrimaryCity(city);
        record.setState(state);
        Set<String> counties = zipCodeService.selectCountyByBean(record);  //通过 city + state 获取相应的  county

        for (String county : counties) {
            if (!StringUtils.isEmpty(county)) {

                String filename = StringUtils.replaceBlankAndComma(state) +
                        "_" + StringUtils.replaceBlankAndComma(city) +
                        "_" + StringUtils.replaceBlankAndComma(county);

                String key = "zillow/" + dir + "/" + filename + ".json";

                System.err.println(key);

                json = downloadService.downloadJsonFromOSS(key);

                //取到值后退出循环
                if (!StringUtils.isEmpty(json)) {
                    break;
                }
            }
        }

        return json;
    }

    public String joinJsonName(Integer type, String city, String state, String county) {
        String filename = StringUtils.replaceBlankAndComma(state) +
                "_" + StringUtils.replaceBlankAndComma(city) +
                "_" + StringUtils.replaceBlankAndComma(county);

        //以下这一些都是以 state + city 命名的
        if (type.equals(ZillowTypeEnum.SaleToListRatio_City.getKey()) ||
                type.equals(ZillowTypeEnum.BuyerSellerIndexCrossGeo_City.getKey()) ||
                type.equals(ZillowTypeEnum.BuyerSellerIndexCrossTime_City.getKey()) ||
                type.equals(ZillowTypeEnum.DaysOnZillow_City.getKey()) ||
                type.equals(ZillowTypeEnum.ForeclosuresPer10Khomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.MedianDailyListings_NSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.MedianDailyListings_SSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.MonthlyListings_NSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.MonthlyListings_SSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.MonthlyTurnover_City.getKey()) ||
                type.equals(ZillowTypeEnum.NewMonthlyListings_NSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.NewMonthlyListings_SSA_AllHomes_City.getKey()) ||
                type.equals(ZillowTypeEnum.SalesPrevForeclosed_Share_City.getKey()) ||
                type.equals(ZillowTypeEnum.SaleToListRatio_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_BottomTier_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_BottomTier_Seas_Adj_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_MiddleTier_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_MiddleTier_Seas_Adj_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_Seas_Adj_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_TopTier_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Counts_TopTier_Seas_Adj_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Prices_BottomTier_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Prices_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Prices_MiddleTier_City.getKey()) ||
                type.equals(ZillowTypeEnum.Sale_Prices_TopTier_City.getKey())) {

            filename = StringUtils.replaceBlankAndComma(state) +
                    "_" + StringUtils.replaceBlankAndComma(city);
        }

        //以下是以 city + state 命名
        if (type.equals(ZillowTypeEnum.DaysOnZillow_City.getKey()) ||
                type.equals(ZillowTypeEnum.DaysOnZillow_City_Repeat.getKey()) ||
                type.equals(ZillowTypeEnum.SaleToListRatio_City.getKey()) ||
                type.equals(ZillowTypeEnum.SaleToListRatio_City_Repeat.getKey())) {
            filename = StringUtils.replaceBlankAndComma(city) +
                    "_" + StringUtils.replaceBlankAndComma(state);
        }

        //以下是以 city + state 命名，但 州是全称，不是缩写，所以需要换
        if (type.equals(ZillowTypeEnum.Sale_Counts_Seas_Adj_City.getKey())
                || type.equals(ZillowTypeEnum.Sale_Counts_Seas_Adj_City_Repeat.getKey())) {
            filename = StringUtils.replaceBlankAndComma(city) +
                    "_" + StringUtils.replaceBlankAndComma(StringUtils.stateAbbreviationToAll(state));
        }

        return filename;
    }

}
